package com.maikobi.maikobi.controller;

import cn.hutool.json.JSONUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Profile;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 队列测试控制器
 * 本类主要用于演示如何使用线程池执行异步任务，并提供接口监控线程池状态
 * 主要功能包括：
 * 1. 添加异步任务到线程池
 * 2. 获取线程池当前状态信息
 *
 * @author Maiko7
 * @since 2025-07-16
 */
@RestController
@RequestMapping("/queue")
@Slf4j
@Profile({"dev", "local"}) // 仅在开发和本地环境中激活
@Tag(name = "队列模块")
public class QueueController {

    @Resource
    private ThreadPoolExecutor threadPoolExecutor;


    /**
     * 假设你是如下配置：
     * new ThreadPoolExecutor(
     *     2,               // corePoolSize 核心线程数
     *     4,               // maximumPoolSize 最大线程数
     *     60L,             // keepAliveTime
     *     TimeUnit.SECONDS,
     *     new LinkedBlockingQueue<>(10) // 最大队列容量为10
     * );
     *
     *
     * 1️⃣ 第一次调用：添加任务(/add)
     * 访问：
     * GET http://localhost:8080/queue/add?name=任务A
     * GET http://localhost:8080/queue/add?name=任务B
     * GET http://localhost:8080/queue/add?name=任务C
     *
     * 此时控制台日志输出类似如下：
     * 任务执行中：任务A, 线程pool-1-thread-1
     * 任务执行中：任务B, 线程pool-1-thread-2
     *
     * 2️⃣ 访问 /queue/get 查看状态
     * 访问：
     * GET http://localhost:8080/queue/get
     * 返回内容示例（JSON）：
     * {
     *   "队列长度": 1,
     *   "任务总数": 3,
     *   "已完成任务数": 0,
     *   "正在工作的线程数": 2
     * }
     *
     *
     * 3️⃣ 再添加多个任务（达到最大线程和队列上限）
     * 继续添加任务：
     *
     * GET /queue/add?name=任务D
     * GET /queue/add?name=任务E
     * GET /queue/add?name=任务F
     * ...
     * 假如你添加了很多任务，直到线程池队列满，最大线程数也被占用，那么后续的任务将被拒绝（除非你自定义了拒绝策略）。
     *
     *
     */



    /**
     * 添加任务到线程池异步执行
     *
     * @param name 任务名称，用于日志记录
     */
    @GetMapping("/add")
    @Operation(summary = "添加任务到线程池异步执行", description = "添加任务到线程池异步执行")
    public void add(String name) {
        CompletableFuture.runAsync(() -> {
            // 记录任务执行信息
            log.info("任务执行中：" + name + ", 执行人：" + Thread.currentThread().getName());
            try {
                // 模拟长时间运行的任务
                Thread.sleep(600000);
            } catch (InterruptedException e) {
                // 异常处理：记录异常信息
                e.printStackTrace();
            }
        }, threadPoolExecutor);
    }

    /**
     * 获取线程池当前状态信息
     *
     * @return 返回包含队列长度、任务总数、已完成任务数和正在工作的线程数的JSON字符串
     */
    @GetMapping("/get")
    @Operation(summary = "获取线程池当前状态信息", description = "获取线程池当前状态信息")
    public String get() {
        Map<String, Object> map = new HashMap<>();
        // 获取并记录队列长度
        int size = threadPoolExecutor.getQueue().size();
        map.put("队列长度", size);
        // 获取并记录任务总数
        long taskCount = threadPoolExecutor.getTaskCount();
        map.put("任务总数", taskCount);
        // 获取并记录已完成任务数
        long completedTaskCount = threadPoolExecutor.getCompletedTaskCount();
        map.put("已完成任务数", completedTaskCount);
        // 获取并记录正在工作的线程数
        int activeCount = threadPoolExecutor.getActiveCount();
        map.put("正在工作的线程数", activeCount);
        // 将线程池状态信息转换为JSON字符串返回
        return JSONUtil.toJsonStr(map);
    }
}
